﻿using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Simple.Tools;
using Simple.Tools.http;
using System;
using System.Collections.Generic;
using System.IO;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;

/*********************************************************
 * 命名空间 Simple.Http
 * 接口名称 Response
 * 开发人员：ADMIN
 * 创建时间：2023/8/17 11:05:17
 * 描述说明：
 * 更改历史：
 * 
 * *******************************************************/
namespace Simple.Http
{
	/// <summary>
	/// 
	/// </summary>
	public class Response : IResponse
	{
		/// <summary>
		/// 
		/// </summary>
		StringBuilder _result;
		/// <summary>
		/// 
		/// </summary>
		private Exception _exception;
		/// <summary>
		/// 
		/// </summary>
		private HttpContextClient _client;
		/// <summary>
		/// 
		/// </summary>
		private HttpRequestMessage _request;
		/// <summary>
		/// 
		/// </summary>
		private HttpResponseMessage _response;

        private bool _isError { get; set; }

		private string _info;

		/// <summary>
		/// 
		/// </summary>
		/// <param name="client">HttpContextClient</param>
		/// <param name="request">HttpRequestMessage</param>
		/// <returns></returns>
		public static async Task<IResponse> Builder(HttpContextClient client,HttpRequestMessage request)
		{
			Response response =new Response(client,request);
			 await response.SendAsync();
			return response;
		}
		/// <summary>
		/// 
		/// </summary>
		/// <param name="client"></param>
		/// <param name="request"></param>
		/// <exception cref="ArgumentNullException"></exception>
		private Response(HttpContextClient client, HttpRequestMessage request)
		{
			if (SimpleCheck.IsNull(client))
			{
				throw new ArgumentNullException("client");
			}
			if (SimpleCheck.IsNull(request))
			{
				throw new ArgumentNullException("request");
			}
			//无内容相应
			_client= client;
			_request = request;
		}
		/// <summary>
		/// 收到相应之后处理回调
		/// </summary>
		/// <typeparam name="TValue"></typeparam>
		/// <param name="action"></param>
		/// <returns></returns>
		public IResponse Then<TValue>(Action<TValue> action)
		{
			try
			{
				if (SimpleCheck.IsNotNull(_exception)) 
				{
					return this;
				}
				TValue value = default;

				if (_result.ToString() is TValue v)
				{
					value = v;
				}
				else if (_result.Length != 0)
				{
					value = JsonConvert.DeserializeObject<TValue>(_result.ToString());
				}

				if (SimpleCheck.IsNotNull(action))
				{
					action(value);
				}
			}
			catch (Exception ex)
			{
				this._exception = ex;
				_client.ErrorInvoke(_response, ex);
			}
			
			return this;
		}

		/// <summary>
		/// 收到相应之后处理回调
		/// info 支持查看请求信息
		/// </summary>
		/// <typeparam name="TValue"></typeparam>
		/// <param name="action"></param>
		/// <returns></returns>
		public IResponse Then<TValue>(Action<TValue,string> action)
		{
			try
			{
				if (SimpleCheck.IsNotNull(_exception))
				{
					return this;
				}
				TValue value = default;

				if (_result.ToString() is TValue v)
				{
					value = v;
				}
				else if (_result.Length != 0)
				{
					value = JsonConvert.DeserializeObject<TValue>(_result.ToString());
				}

				if (SimpleCheck.IsNotNull(action))
				{
					action(value,_info);
				}
			}
			catch (Exception ex)
			{
				this._exception = ex;
				_client.ErrorInvoke(_response, ex);
			}

			return this;
		}

		/// <summary>
		/// 收到相应之后处理回调
		/// </summary>
		/// <param name="action"></param>
		/// <returns></returns>
		public IResponse Then(Action<string> action)
		{
			try
			{
				if (SimpleCheck.IsNotNull(_exception))
				{
					return this;
				}

				if (SimpleCheck.IsNotNull(action))
				{
					action(_result.ToString());
				}
			}
			catch (Exception ex)
			{
				this._exception = ex;
				_client.ErrorInvoke(_response, ex);
			}
			return this;
		}

		/// <summary>
		/// 收到相应之后处理回调
		/// info 支持查看请求信息
		/// </summary>
		/// <param name="action"></param>
		/// <returns></returns>
		public IResponse Then(Action<string,string> action)
		{
			try
			{
				if (SimpleCheck.IsNotNull(_exception))
				{
					return this;
				}

				if (SimpleCheck.IsNotNull(action))
				{
					action(_result.ToString(),_info);
				}
			}
			catch (Exception ex)
			{
				this._exception = ex;
				_client.ErrorInvoke(_response, ex);
			}
			return this;
		}


		/// <summary>
		/// 收到相应之后处理回调
		/// 收到数据文件类型可以使用该方法做回调处理
		/// </summary>
		/// <param name="action"></param>
		/// <returns></returns>
		public IResponse ThenResponse(Action<HttpResponseMessage> action)
		{
			try
			{
				if (_isError)
				{
					return this;
				}
				if (SimpleCheck.IsNotNull(action))
				{
					action(_response);
				}
			}
			catch (Exception ex)
			{
				_exception = ex;
				_client.ErrorInvoke(_response, ex);
			}
			
			return this;
		}

		/// <summary>
		///错误信息的处理
		/// </summary>
		/// <param name="action"></param>
		/// <returns></returns>
		public IResponse ExceptionError(Action<Exception> action)
		{
			if (SimpleCheck.IsNull(action))
			{
				throw new ArgumentNullException(nameof(action));
			}
			if (SimpleCheck.IsNotNull(_exception))
			{
				action.Invoke(_exception);
			}
			return this;
		}

		/// <summary>
		/// 错误的处理
		/// </summary>
		/// <param name="action"></param>
		/// <returns></returns>
		public IResponse Error(Action<HttpResponseMessage,Exception> action)
		{
			if (SimpleCheck.IsNull(action))
			{
				throw new ArgumentNullException(nameof(action));
			}
			if (SimpleCheck.IsNotNull(_exception))
			{
				action.Invoke(_response,_exception);
			}
			return this;
		}
		/// <summary>
		/// 
		/// </summary>
		/// <returns></returns>
		public async Task SendAsync()
		{
			bool _isError=false;
			try
			{
				_response = await _client.GetHttpClient().SendAsync(_request);
				if (SimpleCheck.IsNotNull(_response) &&_response.IsSuccessStatusCode)
				{

					var contentType = _response.Content.Headers.ContentType;
					if (contentType.ToString().Contains(StringExtension.HttpMediaHeader[(int)HttpContextType.Json]) ||
						contentType.ToString().Contains(StringExtension.HttpMediaHeader[(int)HttpContextType.TextPlan])
						)
					{
						_result=new StringBuilder(await _response.Content.ReadAsStringAsync());
					}

					if (!_response.IsSuccessStatusCode)
					{
						_result = new StringBuilder(await _response.Content.ReadAsStringAsync());
						_client.ErrorInvoke(_response, null);
					}
					_info = JsonConvert.SerializeObject(new { responseBody = _result, code = _response.StatusCode.ToString(), fullPath = _response.RequestMessage.RequestUri });
				}
			}
			catch (Exception ex)
			{
				_isError = true;
				_exception = ex;
				_client.ErrorInvoke(_response,ex);
			}
		}
	}
}
